/*
 * @Author: Suo-Yuheng syh15399227325@163.com
 * @Date: 2025-08-24 19:56:02
 * @LastEditors: Suo-Yuheng syh15399227325@163.com
 * @LastEditTime: 2025-08-25 11:10:05
 * @FilePath: /0824/mkfifo_/log.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once

#include<iostream>
#include<stdarg.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/fcntl.h>

#define SIZE 1024
#define Info 0
#define Debug 1
#define Warning 2
#define Error 3
#define Fatal 4

#define Screen 1
#define Onefile 2
#define Classfile 3

#define LogFile "log.txt"

class log
{
public:
    log()
        :_printMethod(Screen)
        ,_path("./log/")
    {}
    
    void Enable(int method)
    {
        _printMethod = method;
    }

    std::string levelTostring(int level)
    {
        switch(level)
        {
            case Info:  return "Info";
            case Debug:  return "Debug";
            case Warning:  return "Warning";
            case Error:  return "Error";
            case Fatal:  return "Fatal";
            default:    return "None";
        }
    }

    // void logmessage(int level, char* format, ...)   // 参数要 从右向左 依次入栈、形参实例化
    // {
    //     time_t t = time(nullptr);
    //     struct tm* ctime = localtime(&t);   // 获取 格式化 时间
    //     char left_buffer[SIZE];

    //     snprintf(left_buffer, sizeof(left_buffer), "[%s][%d-%d-%d %d:%d:%d]", \
    //         levelTostring(level).c_str(), ctime->tm_year+1900, ctime->tm_mon+1, \
    //         ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

    //     va_list s;
    //     va_start(s, format);    // 用第一个形参，初始化 char 指针 format
    //     char right_buffer[SIZE];
    //     vsnprintf(right_buffer, sizeof(right_buffer), format, s);
    //     va_end(s);


    //     // 格式： 默认部分 + 自定义部分
    //     char logtxt[SIZE*2];
    //     snprintf(logtxt, sizeof(logtxt), "%s %s", left_buffer, right_buffer);

    //     // printf("%d-%d-%d %d:%d:%d\n", ctime->tm_year+1900, ctime->tm_mon+1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

    //     // 打印
    //     // printf("%s", logtxt);
    //     printLog(level, logtxt);
    // }

    void printLog(int level, const std::string& logtxt)
    {
        switch(_printMethod)
        {
            case Screen:
                std::cout << logtxt << std::endl;
                break;
            case Onefile:
                printOnefile(LogFile, logtxt);
                break;
            case Classfile:
                printClassfile(level, logtxt);
                break;
            default:
                break;
        }
    }

    void printOnefile(const std::string& logname, const std::string& logtxt)
    {
        std::string logname_ = _path + logname;
        int fd = open(logname_.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0666);
        if(fd < 0)  return;
        write(fd, logtxt.c_str(), logtxt.size());
        close(fd);
    }

    void printClassfile(int level, const std::string& logtxt)
    {
        std::string filename = LogFile;
        filename += ".";
        filename += levelTostring(level);

        printOnefile(filename, logtxt);
    }

    ~log()
    {}

    void operator()(int level, const char* format, ...)
    {
        time_t t = time(nullptr);
        struct tm* ctime = localtime(&t);   // 获取 格式化 时间
        char left_buffer[SIZE];

        snprintf(left_buffer, sizeof(left_buffer), "[%s][%d-%d-%d %d:%d:%d]", \
            levelTostring(level).c_str(), ctime->tm_year+1900, ctime->tm_mon+1, \
            ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

        va_list s;
        va_start(s, format);    // 用第一个形参，初始化 char 指针 format
        char right_buffer[SIZE];
        vsnprintf(right_buffer, sizeof(right_buffer), format, s);
        va_end(s);


        // 格式： 默认部分 + 自定义部分
        char logtxt[SIZE*2];
        snprintf(logtxt, sizeof(logtxt), "%s %s\n", left_buffer, right_buffer);

        // printf("%d-%d-%d %d:%d:%d\n", ctime->tm_year+1900, ctime->tm_mon+1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

        // 打印
        // printf("%s", logtxt);
        printLog(level, logtxt);

    }
private:
    int _printMethod;
    std::string _path;
};

